package com.xx.robot.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.EnumUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.xx.robot.common.constant.ProvinceNameEnum;
import com.xx.robot.thrid.Covid19DxyUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 丁香园疫情服务
 */
@Component
@Slf4j
public class Covid19DxyService {

    private static final String MESSAGE_KEY = "疫情";

    private static final String COVID19_DXY = "Covid19Dxy";
    private static final String COVID19_DXY_OVERALL = "overall";
    private static final String COVID19_DXY_COVID19_AREA_NAME = "covid19_area_name";
    private static final String COVID19_DXY_PROVINCE_DATA = "COVID19_dxy_data";
    private static final String COVID19_DXY_NEWS = "covid19_dxy_news";
    private static final String COVID19_DXY_RUMORS = "covid19_dxy_rumors";

    @Autowired
    private MongoTemplate mongoTemplate;

    public String search(String message) {

        // 删除前后空格
        message = CharSequenceUtil.trim(message);

        // 疫情 总揽
        if (CharSequenceUtil.equals(MESSAGE_KEY, message)) {
            return overall();
        }
        // 疫情 新闻
        if (CharSequenceUtil.endWith(message, "新闻")) {
            return news();
        }
        // 疫情 谣言
        if (CharSequenceUtil.endWith(message, "谣言")) {
            return rumors();
        }

        // 疫情 具体地方
        message = StrUtil.replace(message, MESSAGE_KEY, StrUtil.EMPTY).trim();
        List<JSONObject> resultList = mongoTemplate.find(new Query(Criteria.where("_id").regex(message)), JSONObject.class, COVID19_DXY_PROVINCE_DATA);
        if (CollUtil.isNotEmpty(resultList)) {
            JSONObject result = resultList.get(0);

            String returnMessage = result.getStr("_id") + "地区疫情概览\n现存确诊人数（较昨日增加数量）：" + result.getStr("currentConfirmedCount") +
                    "\n累计确诊人数：" + result.getStr("confirmedCount") +
                    "\n疑似感染人数：" + result.getStr("suspectedCount") +
                    "\n治愈人数：" + result.getStr("curedCount") +
                    "\n死亡人数：" + result.getStr("deadCount") +
                    "\n重症病例人数：" + result.getStr("seriousCount") +
                    "\n死亡人数：" + result.getStr("deadCount") +
                    "\n数据更新时间：" + DateUtil.date(result.getLong("updateTime")) + "\n";

            log.info(returnMessage);
            return returnMessage;
        }


        return CharSequenceUtil.EMPTY;
    }

    /**
     * 疫情总揽
     *
     * @return 疫情总揽
     */
    public String overall() {
        Query query = new Query(Criteria.where("_id").is(COVID19_DXY_OVERALL));
        List<JSONObject> dataList = mongoTemplate.find(query, JSONObject.class, COVID19_DXY);
        if (CollUtil.isNotEmpty(dataList)) {
            return dataList.get(0).getStr("data", CharSequenceUtil.EMPTY);
        }
        return CharSequenceUtil.EMPTY;
    }

    /**
     * 疫情新闻
     *
     * @return 疫情新闻
     */
    public String news() {
        Query query = new Query().with(Sort.by(Sort.Direction.DESC, "pubDate")).limit(5);
        List<JSONObject> dataList = mongoTemplate.find(query, JSONObject.class, COVID19_DXY_NEWS);

        StringBuilder message = new StringBuilder();
        for (JSONObject o : dataList) {
            message.append("标题：").append(o.getStr("title"))
                    .append("\n来源：").append(o.getStr("infoSource"))
                    .append("\n链接：").append(o.getStr("sourceUrl"))
                    .append("\n发布时间：").append(DateUtil.date(o.getLong("pubDate"))).append("\n");
        }
        return message.toString();
    }

    /**
     * 谣言新闻
     *
     * @return 谣言新闻
     */
    public String rumors() {
        Query query = new Query().with(Sort.by(Sort.Direction.ASC, "sort")).limit(5);
        List<JSONObject> dataList = mongoTemplate.find(query, JSONObject.class, COVID19_DXY_RUMORS);

        StringBuilder message = new StringBuilder();
        for (JSONObject o : dataList) {
            message.append("标题：").append(o.getStr("title"))
                    .append("\n辟谣内容概述：").append(o.getStr("mainSummary"))
                    .append("\n详细内容：").append(o.getStr("body")).append("\n\n");
        }
        return message.toString();
    }

    /**
     * 返回自爬虫运行开始（2020 年 1 月 24 日下午 4:00）至今，病毒研究情况以及全国疫情概览，可指定返回数据为最新发布数据或时间序列数据
     *
     * <p> currentConfirmedCount(Incr)	现存确诊人数（较昨日增加数量）值为 confirmedCount (Incr) - curedCount (Incr) - deadCount (Incr)
     * <p> confirmedCount(Incr)	累计确诊人数（较昨日增加数量）
     * <p> suspectedCount(Incr)	疑似感染人数（较昨日增加数量）
     * <p> curedCount(Incr)	治愈人数（较昨日增加数量）
     * <p> deadCount(Incr)	死亡人数（较昨日增加数量）
     * <p> seriousCount(Incr)	重症病例人数（较昨日增加数量）
     * <p> updateTime	数据最后变动时间
     */
    public void overallCrawler() {
        String overallMessage = Covid19DxyUtil.overall();
        if (JSONUtil.isJson(overallMessage)) {
            Map<String, Object> map = new HashMap<>();
            JSONObject result = JSONUtil.parseObj(overallMessage).getJSONArray("results").getJSONObject(0);
            String data = "全国疫情概览\n现存确诊人数（较昨日增加数量）：" + result.getStr("currentConfirmedCount") + "\n"
                    + "累计确诊人数：" + result.getStr("confirmedCount") + "\n"
                    + ("疑似感染人数：" + result.getStr("suspectedCount") + "\n")
                    + ("治愈人数：" + result.getStr("curedCount") + "\n")
                    + ("死亡人数：" + result.getStr("deadCount") + "\n")
                    + ("重症病例人数：" + result.getStr("seriousCount") + "\n")
                    + ("数据最后变动时间：" + DateUtil.date(result.getLong("updateTime")));
            map.put("_id", COVID19_DXY_OVERALL);
            map.put("data", data);
            mongoTemplate.save(map, COVID19_DXY);
            log.info("更新疫情总揽");
        } else {
            log.error("返回结果：{}", overallMessage);
        }
    }

    /**
     * 据库内有数据条目的国家、省份、地区、直辖市列表。
     */
    public void areaCrawler() {

        List<Object> provinceNameList = EnumUtil.getFieldValues(ProvinceNameEnum.class, "name");
        long time = System.currentTimeMillis();
        for (Object o : provinceNameList) {
            String provinceName = o.toString();
            String result = Covid19DxyUtil.area(provinceName);
            if (JSONUtil.isJson(result)) {
                JSONObject results = JSONUtil.parseObj(result).getJSONArray("results").getJSONObject(0);
                JSONObject data = new JSONObject();

                data.set("type", "province");
                data.set("countryName", results.getStr("countryName"));
                data.set("provinceName", results.getStr("provinceName"));
                data.set("_id", results.getStr("provinceShortName"));
                // 现存确诊人数 值为 confirmedCount - curedCount - deadCount
                data.set("currentConfirmedCount", results.getStr("currentConfirmedCount"));
                // 疑似感染人数
                data.set("confirmedCount", results.getStr("confirmedCount"));
                // 疑似感染人数
                data.set("suspectedCount", results.getStr("suspectedCount"));
                // 治愈人数
                data.set("curedCount", results.getStr("curedCount"));
                // 死亡人数
                data.set("deadCount", results.getStr("deadCount"));
                // 其他信息
                data.set("comment", results.getStr("comment"));
                // 更新时间
                data.set("updateTime", DateUtil.date(results.getLong("updateTime")));
                data.set("time", time);
                mongoTemplate.save(data, COVID19_DXY_PROVINCE_DATA);
                log.info("更新{}疫情信息", provinceName);

                // 下属城市的情况
                JSONArray cities = results.getJSONArray("cities");
                if (CollUtil.isNotEmpty(cities)) {
                    for (Object city : cities) {
                        JSONObject cityDataJson = (JSONObject) city;
                        JSONObject cityData = new JSONObject();

                        String cityName = cityDataJson.getStr("cityName");
                        if (CharSequenceUtil.equals(cityName, "境外输入")) {
                            cityName = provinceName + "-" + cityName;
                        }
                        if (CharSequenceUtil.equals(cityName, "待明确地区")) {
                            cityName = provinceName + "-" + cityName;
                        }
                        cityData.set("_id", cityName);

                        cityData.set("provinceName", provinceName);
                        cityData.set("type", "city");
                        cityData.set("countryName", results.getStr("countryName"));

                        // 现存确诊人数 值为 confirmedCount - curedCount - deadCount
                        cityData.set("currentConfirmedCount", cityDataJson.getStr("currentConfirmedCount"));
                        // 疑似感染人数
                        cityData.set("confirmedCount", cityDataJson.getStr("confirmedCount"));
                        // 疑似感染人数
                        cityData.set("suspectedCount", cityDataJson.getStr("suspectedCount"));
                        // 治愈人数
                        cityData.set("curedCount", cityDataJson.getStr("curedCount"));
                        // 死亡人数
                        cityData.set("deadCount", cityDataJson.getStr("deadCount"));
                        // 其他信息
                        cityData.set("comment", cityDataJson.getStr("comment"));
                        // 更新时间
                        cityData.set("updateTime", DateUtil.now());
                        cityData.set("time", time);

                        mongoTemplate.save(cityData, COVID19_DXY_PROVINCE_DATA);
                        //缓存成功，删除历史的数据
                        mongoTemplate.remove(new Query(Criteria.where("time").ne(time)), COVID19_DXY_PROVINCE_DATA);
                        log.info("更新{}疫情信息", cityName);
                    }
                }
            }
        }


    }

    /**
     * 疫情有关的新闻信息，包含数据来源以及数据来源链接
     */
    public void newsCrawler() {
        String result = Covid19DxyUtil.news(1, 10);
        if (CharSequenceUtil.isNotBlank(result)) {
            JSONArray dataList = JSONUtil.parseObj(result).getJSONArray("results");
            long time = System.currentTimeMillis();
            for (Object o : dataList) {
                JSONObject jsonObject = (JSONObject) o;
                jsonObject.set("time", time);
                mongoTemplate.insert(jsonObject, COVID19_DXY_NEWS);
            }
            //缓存成功，删除历史的数据
            mongoTemplate.remove(new Query(Criteria.where("time").ne(time)), COVID19_DXY_NEWS);
            log.info("更新疫情有关的新闻信息");
        }
    }

    /**
     * 疫情有关的谣言以及丁香园的辟谣。
     */
    public void rumorsCrawler() {
        String result = Covid19DxyUtil.rumors(1, 10);
        if (CharSequenceUtil.isNotBlank(result)) {
            JSONArray dataList = JSONUtil.parseObj(result).getJSONArray("results");
            long time = System.currentTimeMillis();
            for (int i = 0, dataListSize = dataList.size(); i < dataListSize; i++) {
                Object o = dataList.get(i);
                JSONObject jsonObject = (JSONObject) o;
                jsonObject.set("time", time);
                jsonObject.set("sort", i + 1);
                mongoTemplate.insert(jsonObject, COVID19_DXY_RUMORS);
            }
            //缓存成功，删除历史的数据
            mongoTemplate.remove(new Query(Criteria.where("time").ne(time)), COVID19_DXY_RUMORS);
            log.info("更新疫情有关的谣言以及丁香园的辟谣");
        }
    }

    /**
     * 更新省市区信息
     */
    public void provinceCity() {
        String result = Covid19DxyUtil.area("provinceName");
        if (CharSequenceUtil.isNotBlank(result)) {
            JSONObject results = JSONUtil.parseObj(result).getJSONObject("results");
            JSONObject data = new JSONObject();

            data.set("type", "province");
            data.set("_id", results.getStr("provinceShortName"));
            mongoTemplate.save(data, COVID19_DXY_COVID19_AREA_NAME);

            // 下属城市的情况
            JSONArray cities = data.getJSONArray("cities");
            if (CollUtil.isNotEmpty(cities)) {
                for (Object city : cities) {
                    JSONObject cityDataJson = (JSONObject) city;

                    JSONObject cityData = new JSONObject();
                    cityData.set("_id", cityDataJson.getStr("cityName"));
                    cityData.set("type", "city");

                    mongoTemplate.save(data, COVID19_DXY_COVID19_AREA_NAME);
                }
            }
        }
    }

    public static void main(String[] args) {
        List<Object> ss = EnumUtil.getFieldValues(ProvinceNameEnum.class, "name");
        log.info("全省：{}", ss);
    }
}
